#include "Source.h"
#include "giconpointer.h"
#include <QDebug>
namespace MessagingMenu
{

Source::Source(Application *parent, const QString &id, const QString &label, const QUrl &icon):
    QObject(parent), m_app(parent), m_isPersistent(false), m_type(COUNT), m_id(id), m_label(label), m_icon(icon),
     m_count(0), m_requiresAttention(false), m_created(false)
{
//    // FIXME: this blindly assumes Application is the parent
//    m_app = qobject_cast<Application *>(parent);
    Q_ASSERT(m_app);
    connect(this, &Source::countChanged, this, &Source::setSourceCount);
    connect(this, &Source::timeChanged, this, &Source::setSourceTime);
    connect(this, &Source::srcStringChanged, this, &Source::setSourceString);
    connect(this, &Source::labelChanged, this, &Source::setSourceLabel);
    connect(this, &Source::iconChanged, this, &Source::setSourceIcon);
    connect(this, &Source::requiresAttentionChanged, this, &Source::setSourceRequiresAttention);
}

bool Source::persistent() const
{
    return m_isPersistent;
}

bool Source::hasCount() const
{
    return m_type == Type::COUNT;
}

bool Source::hasTime() const
{
    return m_type == Type::TIME;
}

bool Source::hasString() const
{
    return m_type == Type::STRING;
}

Source::Type Source::type() const
{
    return m_type;
}

void Source::setSourceCount() {
    if (hasCount() && m_created) {
        messaging_menu_app_set_source_count(m_app->getApp(), m_id.toUtf8().data(), m_count);
    }
}

void Source::setSourceTime()
{
    if (hasTime() && m_created) {
        messaging_menu_app_set_source_time(m_app->getApp(), m_id.toUtf8().data(), m_time.toMSecsSinceEpoch() * 1000);
    }
}

void Source::setSourceString()
{
    if (hasString() && m_created) {
        messaging_menu_app_set_source_string(m_app->getApp(), m_id.toUtf8().data(), m_sourceString.toUtf8().data());
    }
}

void Source::setSourceLabel()
{
    if (m_created)
        messaging_menu_app_set_source_label(m_app->getApp(), m_id.toUtf8().data(), m_label.toUtf8().data());
}

void Source::setSourceIcon()
{
    if (m_created) {
        GIconPointer icon(m_icon);
        messaging_menu_app_set_source_icon(m_app->getApp(), m_id.toUtf8().data(), *icon);
    }
}

void Source::setSourceRequiresAttention()
{
    if (!m_created)
        return;
    if (m_requiresAttention) {
        qDebug() << "Setting requires attention";
        messaging_menu_app_draw_attention(m_app->getApp(), m_id.toUtf8().data());
    } else {
        messaging_menu_app_remove_attention(m_app->getApp(), m_id.toUtf8().data());
    }
}

void Source::setRequiresAttention(const bool requiresAttention)
{
    if (m_requiresAttention == requiresAttention)
        return;

    m_requiresAttention = requiresAttention;
    Q_EMIT requiresAttentionChanged(requiresAttention);
}

void Source::setPosition(const int &position)
{
    if (m_position == position)
        return;

    m_position = position;
    Q_EMIT positionChanged(position);
}

void Source::setTime(const QDateTime &time)
{
    if (m_time == time)
        return;

    m_time = time;
    Q_EMIT timeChanged(time);
}

void Source::setSrcString(const QString &sourceString)
{
    if (m_sourceString == sourceString)
        return;

    m_sourceString = sourceString;
    Q_EMIT srcStringChanged(sourceString);
}

qint32 Source::count() const
{
    return m_count;
}

QDateTime Source::time() const
{
    return m_time;
}

QString Source::srcString() const
{
    return m_sourceString;
}

int Source::position() const
{
    return m_position;
}

void Source::create()
{
    GIconPointer icon(m_icon);
    QByteArray label = m_label.toUtf8();
    messaging_menu_app_append_source(m_app->getApp(), m_id.toUtf8().data(), *icon, label.data());
//    if (m_position >= 0) {
//        switch (m_type) {
//        case TIME:
//            messaging_menu_app_insert_source_with_time(m_app->getApp(), m_position, m_id.toUtf8().data(), *icon, label.data(), m_time.toMSecsSinceEpoch() * 1000);
//            break;
//        case COUNT:
//            messaging_menu_app_insert_source_with_count(m_app->getApp(), m_position, m_id.toUtf8().data(), *icon, label.data(), m_count);
//            break;
//        case STRING:
//            messaging_menu_app_insert_source_with_string(m_app->getApp(), m_position, m_id.toUtf8().data(), *icon, label.data(), m_sourceString.toUtf8().data());
//            break;
//        }
//    } else {
//        switch (m_type) {
//        case TIME:
//            messaging_menu_app_append_source_with_time(m_app->getApp(), m_id.toUtf8().data(), *icon, label.data(), m_time.toMSecsSinceEpoch() * 1000);
//            break;
//        case COUNT:
//            messaging_menu_app_append_source_with_count(m_app->getApp(), m_id.toUtf8().data(), *icon, label.data(), m_count);
//            break;
//        case STRING:
//            messaging_menu_app_append_source_with_string(m_app->getApp(), m_id.toUtf8().data(), *icon, label.data(), m_sourceString.toUtf8().data());
//            break;
//        }
//    }
    m_created = true;
}

void Source::removed()
{
    m_created = false;
}

void Source::messageActivated(MessagingMenuMessage *message, const char *actionId, GVariant *param, gpointer *instance)
{
    Q_UNUSED(message);
    Q_UNUSED(param); // Just amrk unused until we support actions :-)
    qDebug() << "MESSAGE ACTIVATED";
    Source *src = reinterpret_cast<Source *>(instance);
    QString id(actionId);
    Q_EMIT src->menuMessageActivated(id);
}

Message *Source::createMessage(const QString &msgId, const QString &title, const QString &subtitle, const QString &body, const QDateTime &time, const QUrl &icon)
{
    qDebug() << "Creating messaging menu message";
    Message *msg = new Message(this, msgId, icon);
    msg->setTitle(title);
    msg->setSubtitle(subtitle);
    msg->setBody(body);
    msg->setTime(time);
    msg->create();
    g_signal_connect(msg->message(), "activate", G_CALLBACK(Source::messageActivated), this);
    return msg;
}

MessagingMenuApp *Source::getApp()
{
    return m_app->getApp();
}

bool Source::requiresAttention() const
{
    return m_requiresAttention;
}

QString Source::id() const
{
    return m_id;
}

QString Source::label() const
{
    return m_label;
}

QUrl Source::icon() const
{
    return m_icon;
}

void Source::setPersistent(bool isPersistent)
{
    if (m_isPersistent == isPersistent)
        return;

    m_isPersistent = isPersistent;
    Q_EMIT persistentChanged(isPersistent);
}

void Source::setType(Source::Type type)
{
    if (m_type == type)
        return;

    m_type = type;
    Q_EMIT typeChanged(type);
}

void Source::setId(const QString &id)
{
    if (m_id == id)
        return;

    m_id = id;
    Q_EMIT idChanged(id);
}

void Source::setIcon(const QUrl &icon)
{
    if (m_icon == icon)
        return;

    m_icon = icon;
    Q_EMIT iconChanged();
}

void Source::setCount(const qint32 &count)
{
    if (m_count == count)
        return;

    m_count = count;
    Q_EMIT countChanged(count);
}

}
